package com.jamal2362.apktool;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import com.jamal2362.apktool.fragment.EditorFragment;
import com.jamal2362.apktool.fragment.FilesFragment;
import com.jamal2362.apktool.fragment.editor.EditorPagerAdapter;
import com.jamal2362.apktool.fragment.files.FilesAdapter;
import com.jamal2362.apktool.fragment.files.FilesPager;
import com.jamal2362.apktool.fragment.files.FilesPagerAdapter;
import com.jamal2362.apktool.util.FileUtils;
import com.jamal2362.apktool.util.MUtil;
import com.jamal2362.apktool.util.Settings;
import com.jamal2362.apktool.util.TextUtil;

public class MainActivity extends ThemedActivity implements DrawerLayout.DrawerListener {
	private DrawerLayout drawer;
	private EditorFragment editor;
	private FilesFragment files;
	private ImageView mOpenDrawer;
	public static MainActivity INSTANCE; //  ¯\_(ツ)_/¯
	public static final String ACTION_FILTER = "com.jamal2362.apktool.ACTION_FILTER";

	public boolean opeNFiles() {
		if (!drawer.isDrawerOpen(Gravity.LEFT)) {
			drawer.openDrawer(Gravity.LEFT);
			return true;
		} else {
			try {
				if (files.getCurrentId() != 0) {
					showFiles(0);
					return true;
				}
				FilesPagerAdapter adapter = files.getAdapter();
				FilesPager fp = adapter.getFiles();
				FilesAdapter fa = fp.getAdapter();
				return fa.goBack();
			} catch (Exception e) {
				return false;
			}
		}
	}

	public boolean dismissFiles() {
		if (drawer.isDrawerOpen(Gravity.LEFT)) {
			drawer.closeDrawer(Gravity.LEFT);
			return true;
		}
		return false;
	}

	public void showPath(File path) {
		try {
			showFiles(0);
			files.getAdapter().getFiles().getAdapter().refresh(path);
		} catch (Exception e) {
			TextUtil.st(this, getString(R.string.failed_open, path.getAbsolutePath()));
		}
	}

	public void showFiles(int idx) {
		files.setPage(idx);
	}

    @Override
    protected void init(Bundle savedInstanceState) {
        setContentView(R.layout.main);
		INSTANCE = this;
		drawer = findViewById(R.id.drawer);
		drawer.addDrawerListener(this);
		getSupportActionBar().setDisplayOptions(16);
		getSupportActionBar().setCustomView(R.layout.title);
		init(getSupportFragmentManager());
		mOpenDrawer = findViewById(R.id.titleOpenDrawer);
		if (!Settings.lightTheme)
			mOpenDrawer.setImageResource(R.drawable.ic_menu_dark);
		mOpenDrawer.setOnClickListener(new OnClickListener()
			{
				public void onClick(View v) {
					if (drawer.isDrawerOpen(Gravity.LEFT)) {
						drawer.closeDrawer(Gravity.LEFT);
					} else {
						drawer.openDrawer(Gravity.LEFT);
					}
				}
			});
		mOpenDrawer.setOnLongClickListener(new OnLongClickListener()
			{
				@Override
				public boolean onLongClick(View p1) {
					// throw new NullPointerException("Test!");
					Runnable reset = new Runnable()
					{
						@Override
						public void run() {
							Settings.resetFiles(MainActivity.this);
						}
					};
					MUtil.createDialog(MainActivity.this, getString(R.string.mreset_app_files), reset);
					return true;
				}
			});
    }

	public void init() {
		onNewIntent(getIntent());
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		final Uri data = intent.getData();
		if (data == null || !intent.getAction().equals(Intent.ACTION_VIEW))
			return;
		if (data.getLastPathSegment().toLowerCase().endsWith(".apks") || data.getLastPathSegment().toLowerCase().endsWith(".xapk")) {
			try {
				final File temp = File.createTempFile("A_TempSplit", ".tmp", getCacheDir());
				InputStream fis;
				if (data.getScheme().equals("content")) {
					fis = getContentResolver().openInputStream(data);
				} else {
					File file = new File(data.getPath());
					fis = new FileInputStream(file);     
				}
				OutputStream out = new FileOutputStream(temp);
                IOUtils.copy(fis, out);
                fis.close();
                out.close();
				final int[] select = new int[]{0};
				String[] values = {getString(R.string.mantisplit)};
				if (Build.VERSION.SDK_INT >= 21) {
					values = new String[]{getString(R.string.mantisplit), getString(R.string.install), getString(R.string.install_sign)};
				}
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle(data.getLastPathSegment());
				builder.setSingleChoiceItems(values, select[0], new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialogInterface, int item) {
							select[0] = item;
						}
					}
				);
				builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface p1, int p2) {
							FileUtils.openApks(MainActivity.this, temp, data.getLastPathSegment(), files.getAdapter().getFiles().getAdapter(), select[0], true);
						}
					});
				builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener()
					{
						@Override
						public void onClick(DialogInterface p1, int p2) {
							temp.delete();
						}
					});
				builder.setOnCancelListener(new DialogInterface.OnCancelListener()
					{
						@Override
						public void onCancel(DialogInterface p1) {
							temp.delete();
						}
					});
				builder.create().show();
			} catch (Exception e) {
				TextUtil.st(this, getString(R.string.failed_open, data.toString()));
			}
		} else {
			editor.open(data, null);
			dismissFiles();
		}
		intent.setData(null);
	}

	private void init(FragmentManager supportFragmentManager) {
		Fragment fragment = supportFragmentManager.findFragmentById(R.id.editor);
		FilesFragment files;
		if (fragment == null) {
			EditorFragment editor = new EditorFragment();
			files = new FilesFragment();
			supportFragmentManager.beginTransaction().
				add(R.id.editor, editor).
				add(R.id.leftView, files).
				commit();
			this.editor = editor;
		} else {
			editor = (EditorFragment) fragment;
			files = (FilesFragment) supportFragmentManager.findFragmentById(R.id.leftView);
		}
		files.bind(editor);
		this.files = files;
	}

	private long lastClicked = 0l;

	@Override
	public void onBackPressed() {
		if (editor.closeSearch() || opeNFiles() || editor.collapseItem())
			return;
		long curClick = System.currentTimeMillis();
		if (curClick - lastClicked > 2000) {
			Toast.makeText(this, R.string.click_once_more, Toast.LENGTH_SHORT).show();
			lastClicked = curClick;
			return;
		}
		checkExit();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		boolean ste = FileUtils.fileExists(this, "stack.trace");
		menu.findItem(R.id.stack).setVisible(ste);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.exit:
				checkExit();
				break;

			case R.id.settings:
				Intent i = new Intent(this, SettingActivity.class);
				startActivity(i);
				break;

			case R.id.stack:
				Intent j = new Intent(this, CrashActivity.class);
				startActivity(j);
				break;

			default:
				return false;
		}
		return true;
	}

	private void checkExit() {
		if (editor.hasUnSavedEditor())
			showSaveDialog();
		else
			finish();
	}

	@Override
	protected void onResume() {
		super.onResume();
		// INSTANCE = this;
		IntentFilter intentFilter = new IntentFilter(ACTION_FILTER);
        intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        registerReceiver(broadcastReceiver, intentFilter);
		invalidateOptionsMenu();
	}

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(final Context context, Intent intent) {
            final String pn = intent.getStringExtra("packageName");
			final boolean success = intent.getBooleanExtra("success", false);
			final int status = intent.getIntExtra("status", -999);
			final String message = intent.getStringExtra("message");
			if (success) {
				Runnable launch = new Runnable()
				{
					@Override
					public void run() {
						if (pn != null)
							MUtil.launchApp(context, pn);
					}
				};
				MUtil.createDialog(context, context.getString(R.string.install_success), R.string.launch_app, launch);
			} else {
				Runnable copy = new Runnable()
				{
					@Override
					public void run() {
						if (message != null)
							TextUtil.setClipboard(context, message);
					}
				};
				MUtil.createDialog(context, context.getString(R.string.install_fail, status) + "<br>" + context.getString(R.string.errorf, message), R.string.copy, copy);
			}
            abortBroadcast();
        }
    };

	@Override
	public void finish() {
		EditorPagerAdapter.INSTANCE.exit();
		super.finish();
	}

	private void showSaveDialog() {
		DialogInterface.OnClickListener l = new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface p1, int p2) {
				if (p2 == DialogInterface.BUTTON_NEUTRAL)
					return;
				if (p2 == DialogInterface.BUTTON_POSITIVE)
					editor.save(true, false);
				finish();
			}
		};
		new AlertDialog.Builder(this).
			setTitle(R.string.save_file).
			setMessage(R.string.save_file_msg).
			setPositiveButton(R.string.yes, l).
			setNegativeButton(R.string.no, l).
			setNeutralButton(R.string.cancel, l).
			show();
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		changeLeft();
	}

	private void changeLeft() {
		View parent = drawer;
		View child = parent.findViewById(R.id.leftView);
		int width = parent.getWidth() / 5 * 4;
		// int width = parent.getWidth();
		ViewGroup.LayoutParams params = child.getLayoutParams();
		params.width = width;
		child.setLayoutParams(params);
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		new Handler().postDelayed(new Runnable()
			{
				@Override
				public void run() {
					changeLeft();
				}
			}, 100);
	}

	@Override
	protected void onPause() {
		super.onPause();
		editor.save(true, false);
	}

	@Override
	public void onDrawerSlide(View p1, float p2) {
		// TODO: Implement this method
	}

	@Override
	public void onDrawerOpened(View p1) {
		files.focus();
		drawer.requestDisallowInterceptTouchEvent(false);
	}

	@Override
	public void onDrawerClosed(View p1) {
		editor.focus();
		drawer.requestDisallowInterceptTouchEvent(true);
	}

	@Override
	public void onDrawerStateChanged(int p1) {
		// TODO: Implement this method
	}
}
